import Cesium from '../Ces/Cesium'

import WeVectorImageryLayerProvider from './WeVectorImageryLayerProvider'

class WeVectorImageryLayer extends Cesium.ImageryLayer {
  [x: string]: any
  hasRenderObj: boolean = false
  constructor(options) {
    let imageryProvider = options.imageryProvider
    if (!imageryProvider) {
      imageryProvider = new WeVectorImageryLayerProvider(options)
    }
    super(imageryProvider, options)
    this.hasRenderObj = false

  }

  get ready() {
    return this._imageryProvider._ready
  }

  _createTextureWebGL(context, imagery) {
    const render = this.imageryProvider.render

    const image = imagery.image
    const { renderObj } = image
    let texture = image.texture
    if (!texture) {
      const sampler = new Cesium.Sampler({
        minificationFilter: this.minificationFilter,
        magnificationFilter: this.magnificationFilter,
      })

      if (Cesium.defined(image.internalFormat)) {
        texture = new Cesium.Texture({
          context,
          pixelFormat: image.internalFormat,
          width: image.width,
          height: image.height,
          source: {
            arrayBufferView: image.bufferView,
          },
          sampler,
        })
      } else if (image instanceof HTMLImageElement
        || image instanceof HTMLCanvasElement
        || image instanceof ImageBitmap
      ) {
        texture = new Cesium.Texture({
          context,
          source: image,
          pixelFormat: this._imageryProvider.hasAlphaChannel
            ? Cesium.PixelFormat.RGBA
            : Cesium.PixelFormat.RGB,
          sampler,
        })
      } else {
        texture = new Cesium.Texture({
          context,
          source: {
            width: 1,
            height: 1,
            arrayBufferView: new Uint8Array([0, 0, 0, 0]),
          },
          flipY: false,
        })
      }
    }


    if (renderObj) {
      imagery.weGuid = render._weGuid
      const { x, y, level } = imagery
      render.addCache(x, y, level, renderObj)

      const releaseReference = imagery.releaseReference
      imagery.releaseReference = () => {
        const referenceCount = releaseReference.bind(imagery)()
        if (referenceCount === 0) {
          render.removeCache(x, y, level)
        }
        return referenceCount
      }

      this.hasRenderObj = true
    }

    return texture
  }

  update(frameState) {
    if (!this.ready || !frameState.passes.render) {
      return
    }

    const render = this.imageryProvider.render

    if (this.hasRenderObj) {
      render.resetVisible()

      const scene = frameState.camera._scene
      scene.globe._surface.forEachRenderedTile((tile) => {
        tile.data.imagery.forEach((element) => {
          const imagery = element.readyImagery
          if (imagery) {
            render.filterVisible(imagery)
          }
        })
      })
    }

    if (render && render.update) {
      render.update(frameState)
    }
  }

  destroy() {
    this.imageryProvider.render = this.imageryProvider.render && this.imageryProvider.render.destroy()
    return super.destroy()
  }

  isDestroyed() {
    return false
  }
}

export default WeVectorImageryLayer
